var UCD = UCD || {Core:jQuery};
(function(ucd,$)
{
	var COLOR;
	var id = 0;
	var tool;
	var defaultOptions =
	{
		height : 800,
		width : 1920,
		pathMargin : { left : 1 , top: 1 , right : 1 },	//路径距节点的距离
		nodeSpace : 10,		//节点之间的距离	
		colSpace: 300,
		rowSpace: 43,
		startY: 10,
		startX: 0
	};

	var defaultNode = 
	{
		fill:"black",
		inPathY:{}, 		//记录path的起点或终点的y坐标	流入
		outPathY:{},  		//记录path的起点或终点的y坐标	流出
		inLinks : [],			//记录流入方边的索引
		outLinks : []			//记录流出方边的索引
	};

	var defaultLink =
	{
		strokeWidth: 10
	}

	function Sankey(container, option)
	{	
		this.$container = $(container);
		this.container = document.createElement("div");
		this.$container.append(this.container);
		this.owner = new UCD.MyD3();
		this.owner.container(this.container);
		this.owner.attr("id", "Sankey_" + id++).css('position', 'relative');
		this.options = $.extend({}, defaultOptions, option);
	}

	var proto = Sankey.prototype;

	proto.init = function()
	{
		this.dataCheck();
		var opts = this.options;

		tool = this.owner.tool;

		//所有this绑定的数据申明，用于后面的垃圾回收和数据更新
		this.nodesData = [];
		this.linksData = [];
		
		this.svg = this.owner.append('svg').attr('height', opts.height).attr('width', opts.width);

		this.g = this.svg.append('g');

		this.nodeInit();
		this.tipInit();

		this.eventsBind();
	}

	proto.dataCheck = 
	function _dataCheck(self)
	{

	}

/**********************************************
	Node Module
**********************************************/
	proto.nodeInit =
	function _nodeInit()
	{
		this.nodeDataBind();
		this.pathInit();		//为了让节点在后添加位于上层图层
		this.nodeAppend();

		console.log(this.nodesData);
		// this.nodeDIY();	//自行定制化函数，配置相关数据绑定, 具体都在nodesData中
	}

	//节点所需数据计算
	proto.nodeDataBind =
	function _nodeDataBind()
	{
		var opts = this.options;
		var nodes = opts.json.nodes;
		var nodeData;

		for(var index in nodes)
		{
			nodeData = $.extend(true, {}, defaultNode, nodes[index]);		//默认值

			/*X Y position*/	//数据的一般/标准化normalize

			nodeData.YYx = parseInt(nodeData.col) * opts.colSpace + opts.startX;

			if(parseInt(nodeData.col) === 1 )
			{
				nodeData.YYx += 600;
			}

			nodeData.YYy = parseInt(nodeData.row) * opts.rowSpace + opts.startY;

			/*inPath Y position*/
			nodeData.inPathY = nodeData.YYy;

			/*outPath Y position*/
			nodeData.outPathY = nodeData.YYy;

			//进行索引，作为一个全局变量使用
			this.nodesData[index] = nodeData;				
		}
	}


	//添加节点并设置属性
	proto.nodeAppend =
	function _nodeAppend () 
	{
		var opts = this.options;
		var nodesData = this.nodesData;
		var nodeData;

		for(var index in nodesData)
		{
			nodeData = nodesData[index];

			var g = this.g.append('rect').attr('x', nodeData.YYx).attr('y', nodeData.YYy);
				
			//下面与添加无关					

			//相互索引
			g._yData = nodeData;
			nodeData.g = g;

			g.owner.myD3 = g;
		}
	}

/**********************************************
	Path Module
**********************************************/
	proto.pathInit =
	function _pathInit()
	{

		this.pathDataBind();
		this.pathAppend();

		console.log(this.linksData);
		// this.pathDIY();	//自行定制化函数，配置相关数据绑定, 具体都在linksData中
	}

	proto.pathDataBind = 
	function _pathDataBind()
	{
		var opts = this.options;
		var links = opts.json.links;
		var nodesData = this.nodesData;
		var linkData;
		var source;	//起点
		var target;

		for(var index in links)
		{
			linkData = $.extend(true, {}, defaultLink, links[index]);
			source = nodesData[linkData.source];
			target = nodesData[linkData.target];

			//起点记录流出，目标点记录流入
			source.outLinks.push(linkData);
			target.inLinks.push(linkData);

			//当前处理边相关数据绑定
			linkData.d = this.dGet(source.YYx + 600, source.YYy + 20, target.YYx - 3 , target.YYy + 20);

			//进行索引，作为一个全局变量使用
			this.linksData[index] = linkData;	
		}
	}

	proto.dGet =	//贝塞尔
	function (sourceX, sourceY, targetX, targetY)
	{
		// console.log(sourceX + sourceY, targetX, targetY);
		var targetX2= targetX-40;
		return "M" + (sourceX ) + ',' + (sourceY) + ' Q'+ ( (sourceX + targetX -100) / 2 ) + ',' + ( sourceY ) 
		+ ' ' + (sourceX + targetX) / 2 + ',' + ((sourceY + targetY) / 2)
		+ ' T' + (targetX2) + ',' + ( targetY);
	}

	// proto.dGet =	//贝塞尔2
	// function (sourceX, sourceY, targetX, targetY)
	// {
	// 	// console.log(sourceX + sourceY, targetX, targetY);

	// 	return "M" + (sourceX ) + ',' + (sourceY) + ' L' + (sourceX + (targetX - sourceX) / 6 ) + ',' + (sourceY) + ' Q'+ ( (sourceX + targetX) / 2 ) + ',' + (sourceY) 
	// 	+ ' ' + (sourceX + targetX) / 2 + ',' + ((sourceY + targetY) / 2)
	// 	+ ' T' + (targetX - (targetX - sourceX) / 6 ) + ',' + ( targetY) + ' L' + targetX + ',' + targetY;	
	// }

	// proto.dGet =	//直线
	// function (sourceX, sourceY, targetX, targetY)
	// {
	// 	return "M" + (sourceX ) + ',' + (sourceY) + ' L' + (targetX) + ',' + ( targetY);	
	// }

	proto.pathAppend =
	function _pathAppend() 
	{
		var links = this.linksData;
		var nodes = this.nodesData;
		var linkData;
		var path;

		for(var index in links)
		{
			path = this.g.append('path');
			linkData = links[index];

			path.attr('d', linkData.d).attr('fill','none').addClass('link').attr('stroke-width', linkData.strokeWidth * linkData.percent);

			//下面与添加无关
			//相互索引
			linkData.path = path;
			path._yData = linkData;
		}
	}


/**************************************
	修改更新 Module
**************************************/
	proto.inLinksUpdate = 
	function _inLinksUpdate(index)	//index为处理点的索引
	{
		var nodesData = this.nodesData;
		var targetData = nodesData[index];
		var inLinks = targetData.inLinks;
		var sourceData;

		for(var i in inLinks)
		{
			sourceData = nodesData[ inLinks[i].source ];
			inLinks[i].d = this.dGet(sourceData.YYx, sourceData.YYy, targetData.YYx, targetData.YYy);
			// console.log(inLinks[i]);
			inLinks[i].path.attr('d', inLinks[i].d);
		}
	}

	proto.outLinksUpdate = 
	function _outLinksUpdate(index)	//index为处理点的索引
	{
		var nodesData = this.nodesData;
		var sourceData = nodesData[index];
		var outLinks = sourceData.outLinks;
		var targetData;

		for(var i in outLinks)
		{
			targetData = nodesData[ outLinks[i].target ];
			outLinks[i].d = this.dGet(sourceData.YYx, sourceData.YYy, targetData.YYx, targetData.YYy);
			outLinks[i].path.attr('d', outLinks[i].d);
		}
	}

/*******************************
	eventsBind Module
********************************/
	proto.eventsBind = function()
	{
		var self = this;
		var $link = $('#Sankey_0 .link');
		console.log($link);
		$('#Sankey_0').on('mouseenter', 'rect', function(event) {
			$link.attr('class', 'link fade');
			event.preventDefault();
			/* Act on the event */
			// console.log( this );
			$(this).attr('class', 'hover');
			self.parentsHover(this.d3._yData);

		}).on('mouseleave', 'rect', function(event) {
			event.preventDefault();
			$link.attr('class', 'link');
			/* Act on the event */
			// console.log(this.myD3._yData);
			$(this).attr('class', '');
			self.parentsDisHover(this.d3._yData);
		});
	}

	proto.parentsHover = function(nodeData)
	{
		var inLinks = nodeData.inLinks;
		var outLinks = nodeData.outLinks;
		var nodesData = this.nodesData;
		var curLink;

		for(var i in inLinks)
		{
			curLink = inLinks[i];
			curLink.path.removeClass('fade');
			nodesData[curLink.source].g.addClass('hover');
		}

		for(var i in outLinks)
		{
			curLink = outLinks[i];
			curLink.path.removeClass('fade');
			nodesData[curLink.target].g.addClass('hover');
		}
	}

	proto.parentsDisHover = function(nodeData)
	{
		var inLinks = nodeData.inLinks;
		var outLinks = nodeData.outLinks;
		var nodesData = this.nodesData;
		var curLink;

		for(var i in inLinks)
		{
			curLink = inLinks[i];
			// curLink.path.removeClass('hover');
			nodesData[curLink.source].g.removeClass('hover');
		}

		for(var i in outLinks)
		{
			curLink = outLinks[i];
			// curLink.path.removeClass('hover');
			nodesData[curLink.target].g.removeClass('hover');
		}
	}

/****************************************************************
		tip Module
*****************************************************************/
	proto.tipInit = function()
	{
		this.$container.append('<div class="node-tip"><div>')
	}



	ucd.Sankey = Sankey;

})(UCD,UCD.Core);